﻿// ***************************************************************
//  any_data   version:  1.0   ·  date: 05/30/2010
//  -------------------------------------------------------------
//  万能变量基类
//  -------------------------------------------------------------
//  Copyright (C) 2010 - All Rights Reserved
// ***************************************************************
// 
// ***************************************************************
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
#pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#ifndef ccs_util_data_any_data_h__
#define ccs_util_data_any_data_h__

#include <boost/thread.hpp>
#include <boost/intrusive_ptr.hpp>

#include "ccs_util/archive.hpp"
#include "ccs_util/memory.hpp"



#ifdef ccs_validate_multithread_protect
#define interlocked_increment_integer BOOST_INTERLOCKED_INCREMENT
#define interlocked_decrement_integer BOOST_INTERLOCKED_DECREMENT
#else // ccs_validate_multithread_protect
#define interlocked_increment_integer(i) ++i
#define interlocked_decrement_integer(i) --i
#endif // ccs_validate_multithread_protect

namespace ccs
{
	class serialisable
	{
	public:
		virtual ~serialisable() {}

		virtual void serialise(iarchive& iar) = 0;
		virtual void serialise(oarchive& oar) = 0;
	};


	class basic_self_event_data
	{
	public:
		event::connection observe(std::string const& eventName, event::slot2 const& handler)
		{
			event::event_set2::iterator it = observers.find(eventName);
			if (it == observers.end())
			{
				throw std::exception("Not include this event");
			}
			return it->second.connect(handler);
		}

	protected:
		event::event_set2 observers;
	};

	class any_data;

	void intrusive_ptr_add_ref(any_data* p);
	void intrusive_ptr_release(any_data* p);

	class any_data : public serialisable
	{
	public:
		friend void intrusive_ptr_add_ref(any_data* p);
		friend void intrusive_ptr_release(any_data* p);

		any_data(): ref_count_(0)
		{
		}
		virtual ~any_data() {}

		void add_ref()
		{
			interlocked_increment_integer(ref_count_);
		}
		void release()
		{
			interlocked_decrement_integer(ref_count_);
			if (ref_count_ <= 0)
			{
				_release_object();
			}
		}

		virtual event::connection observe(std::string const& eventName, event::slot2 const& handler){
			throw std::exception("NoImplement");
		};

		virtual void trigger_observer(){}

		bool is_self_event() const { return self_event_; }

	protected:

		virtual void _release_object() = 0;

		int32
#ifdef ccs_validate_multithread_protect
			volatile
#endif // ccs_validate_multithread_protect
			ref_count_;

		bool self_event_;
	};
	typedef boost::intrusive_ptr<any_data> any_data_ptr;

	inline void intrusive_ptr_add_ref(any_data* p)
	{
		p->add_ref();
	}
	inline void intrusive_ptr_release(any_data* p)
	{
		p->release();
	}
}

#endif /*ccs_util_data_any_data_h__*/